package com.dragon.quartz.utils;

import com.dragon.quartz.constant.QuartzConstant;
import com.dragon.quartz.domain.QuartzJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.util.Date;

/**
 * 抽象quartz调用
 *
 * @author dragon
 * @version 1.0
 * @date 2024/9/6 14:58
 */
public abstract class AbstractQuartzJob implements Job {

    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);

    /**
     * 线程本地变量
     */
    private static final ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        QuartzJob job = new QuartzJob();
        BeanUtils.copyProperties(jobExecutionContext.getMergedJobDataMap().get(QuartzConstant.TASK_PROPERTIES), job);

        try {
            before(jobExecutionContext, job);
            doExecute(jobExecutionContext, job);
            after(jobExecutionContext, job, null);
        } catch (Exception e) {
            log.error("Quartz任务执行异常 {}", e.getMessage(), e);
            after(jobExecutionContext, job, e);
        }
    }

    /**
     * 执行前
     *
     * @param context 工作执行上下文对象
     * @param job     系统计划任务
     */
    protected void before(JobExecutionContext context, QuartzJob job) {
        threadLocal.set(new Date());
    }

    /**
     * 执行后
     *
     * @param context 工作执行上下文对象
     * @param job     系统计划任务
     */
    protected void after(JobExecutionContext context, QuartzJob job, Exception e) {
        Date startTime = threadLocal.get();
        Date stopTime = new Date();
        threadLocal.remove();

        long runMs = stopTime.getTime() - startTime.getTime();

        log.warn("Quartz任务执行完毕，任务组：{} 任务名：{} 执行类：{} 总共耗时：{} 毫秒 失败原因：{}",
            job.getJobGroup(),
            job.getJobName(),
            job.getInvokeTarget(),
            runMs,
            e == null ? "" : e.getMessage()
        );
    }

    /**
     * 执行方法，由子类重载
     *
     * @param context 工作执行上下文对象
     * @param job     系统计划任务
     * @throws Exception 执行过程中的异常
     */
    protected abstract void doExecute(JobExecutionContext context, QuartzJob job) throws Exception;

}
